#ifndef _CallpTypeDefinitions_h_
#define _CallpTypeDefinitions_h_
////////////////////////////////////////////////////////////////////////////////
/// @file CallpTypeDefinitions.h
/// @brief This file contains the common Callp type definitions.
///
/// This file defines the common Callp type definitions such as PhyCellIdType.
///
/// Maintained by: LTE eNB Callp Application Team
///
/// Copyright(c) 2009-2010 Nanocell, All Rights Reserved
///
/// CONFIDENTIALITY AND RESTRICTED USE
///
/// This software, including any software of third parties embodied herein,
/// contains information and concepts which are confidential to Nanocell
/// and such third parties. This software is licensed for use
/// solely in accordance with the terms and conditions of the applicable
/// license agreement with Nanocell or its authorized distributor.
////////////////////////////////////////////////////////////////////////////////

#include <cstring>
#include <iostream>
#include <stdint.h>
#include <ostream>
#include "CallpConstants.h"
#include "CallpTypeDefinitions_xml.h"
#include "CallpAsnTypes.h"


using namespace std;

// Temporary limitation on MAX_ENB_DRB_FLOWS:
// To allow for increased PDCP queue depths the max number of flows is being
// reduced by a factor of 3 (from 999 to 333). This will allow the current
// maximum PDCP queue size to be increased by a factor of 3 without affecting
// memory requirements.
//
// This change is temporary as it will not support the 128 UE capacity
// requirement. There will be a PDCP activity to address the 0D1 changes to
// support the max capacity UEs from a PDCP perspective. At that point we will
// be able to remove this temporary limitation.
//#define MAX_ENB_DRB_FLOWS 1800//600//333//999 // This number must be divisible by 3.
#define MAX_ENB_DRB_FLOWS 64 //600//333//999 // This number must be divisible by 3.

// Definitions for UmSnSize
#define UM_10BIT_SN_SIZE 10
#define UM_5BIT_SN_SIZE 5

// Max number of S1 Endpoint
#define MAX_S1_ENDPOINTS 16

// Max number of PLMN IDs per cell
#define MAX_PLMN_IDS_PER_CELL 6

// Forward declarations
class SignalingFlowMessageHandler;
namespace L2Cell_ns
{
    class FlowPubIf;
}

typedef struct PhyCellIdList
{
    uint8_t numOfCell;
    PhyCellIdType phyCellId[MAXIMUM_CELLS_MEASURED];
} PhyCellIdList;

typedef struct CellIdWithinEnbList
{
	uint8_t numOfCell;
	uint16_t cellIdWithinEnb[MAXIMUM_CELLS_MEASURED];
}CellIdWithinEnbList;

typedef struct UintEcgi
{
	uint32_t      plmnIdU32_;
	GblCellIdType glbCellId_;

	UintEcgi()
	{
		memset(this, 0, sizeof(UintEcgi));
	}

	bool operator<(const UintEcgi& rhs) const;
	bool operator==(const UintEcgi& rhs) const;
}UintEcgi;

inline bool UintEcgi::operator<( const UintEcgi& rhs) const
{
	if( plmnIdU32_ < rhs.plmnIdU32_ )
	{
		return true;
	}
	else if( plmnIdU32_ == rhs.plmnIdU32_ )
	{
		if( glbCellId_ < rhs.glbCellId_ )
		{
			return true;
		}
	}

	return false;
}

inline bool UintEcgi::operator==(const UintEcgi& rhs) const
{
	return ( ( rhs.plmnIdU32_ == plmnIdU32_ ) &&
		     ( rhs.glbCellId_ == glbCellId_ ) );
}

typedef struct UintEcgiList
{
    uint8_t numOfCell;
    UintEcgi ecgis[MAXIMUM_CELLS_MEASURED];

    UintEcgiList()
    {
    	memset(this, 0, sizeof(UintEcgiList));
    }

} UintEcgiList;

typedef struct EcgiPciPair
{
	UintEcgi ecgi;
	PhyCellIdType pci;

	EcgiPciPair()
	{
		memset(this, 0, sizeof(EcgiPciPair));
	}

}EcgiPciPair;

typedef struct EcgiPciList
{
	uint8_t numOfCell;
	EcgiPciPair ecgiPcis[MAXIMUM_CELLS_MEASURED];

	EcgiPciList()
	{
		memset(this, 0, sizeof(EcgiPciList));
	}

}EcgiPciList;

typedef struct PciFreqPair
{
	PhyCellIdType pci_;
	uint16_t freq_;

	PciFreqPair()
	{
		memset(this, 0, sizeof(PciFreqPair));
	}
}PciFreqPair;

typedef uint16_t FlowIdType;

typedef uint32_t EndPointIdentifier_t;

typedef uint32_t TeIdType;
const TeIdType InvalidTeId = 0;

const uint8_t MAX_NUM_OF_MISSING_PDU = 100;

const uint16_t MAX_NUM_MISSING_SN = 4096;

const uint8_t MAX_EPS_BEARER_NUM = 32;

static const uint16_t MAX_NUM_OF_ERABS_PER_CELL = 8*200;

static const uint8_t transportLayerAddressSize_c = 20;

typedef uint8_t CellProcessIdType;

typedef uint16_t TraceRecordingSessionRef;
typedef uint64_t UeTraceSessionRefType;

namespace LteApp
{
    struct InterRatPhyCellIdItemType
    {
        PhyCellIdType phyCellId_;
        uint16_t pilotStrength_;

        InterRatPhyCellIdItemType()
        {
            memset(this, 0, sizeof(InterRatPhyCellIdItemType));
        }
    };

   // define trace reference type as 6 bytes struct
   // this definition will be updated based on data model once the data model is available
   struct TraceReferenceType
   {
       uint8_t value[6];
   };


   struct CellBasedCallTraceData
   {
       TraceReferenceType s1TraceReference;
       TraceReferenceType x2TraceReference;
       TraceReferenceType uuTraceReference;
       uint32_t s1Depth;
       uint32_t x2Depth;
       uint32_t uuDepth;
   };

    typedef enum
    {
        INDICATION,
        REQUEST,
        RESPONSE
    } InterfaceMessageType;

    enum MeasReportDeleteType
    {
        DEL_TYPE_INTERFREQEVENTA3 = 0,
        DEL_TYPE_ANREVENTA4,
        DEL_TYPE_ANRPERIODICAL,
        DEL_TYPE_INTERFREQEVENTA5,
        DEL_TYPE_EVENTB1,
        DEL_TYPE_EVENTB2,
        DEL_TYPE_ICICEVENTA3,
        MAX_DEL_TYPE
    };

    enum MeasReportType
    {
        UNKNOWN = 0,
        EVENTA1 = 1,
        EVENTA2,
        EVENTA3,
        EVENTA4,
        EVENTA5,
        EVENTB1,
        EVENTB2,
        REPORTCGI,
        REPORTSTRONGESTCELLS,
        REPORTSTRONGESTCELLSFORSON
    };

    // reset reason in reset control
    typedef enum
    {
        S1_RESET = 1,
        CELL_LOCK,
        CELL_RESET,
        ENB_LOCK,
        ENB_RESET,
        L2_RESET,
        BH_RESET,
        PLMNID_CHANGED,
        RESET_UNSPECIFIED
    }ResetReleaseReason;

    //
    // Backhaul Interface
    //
    struct BackhaulReturnCodeType
    {
        enum type
        {
            // request was successful
            SUCCESS                   = 1,
            // Passed in parameters are incorrect
            GTPU_FAIL_INVALID_PARAMS,
            // Routing table is full
            GTPU_FAIL_TABLE_SATURATED,
            // Can't find resource
            GTPU_FAIL_NO_MATCH,
            // generic GTP-U error
            GTPU_FAIL,
            // Generic Echo setup error
            ECHO_FAIL,
            // Waiting for Echo response
            ECHO_PENDING,
            ///@todo PDCP failure codes are TBD
            PDCP_FAIL,
            PDCP_PENDING,
            // ONLY USE IF *IMPOSSIBLE* TO FIGURE OUT PROBLEM
            UNKNOWN_FAILURE
        }; // returnCode;
    };
    typedef enum BackhaulReturnCodeType::type BackhaulReturnCode;
    typedef BackhaulReturnCodeType BackhaulRC;

    struct BackhaulExternAppMsgType
    {
        enum type
        {
            CREATE_DRB_FLOW = 1,
            PDCP_SN_STATUS,
            ECHO_REQUEST,
            NULL_BH_MSG_TYPE
        };
    };

    typedef enum BackhaulExternAppMsgType::type BackhaulExternAppMsg;

    typedef void (*GenericBhAsyncResponseCallBack) (void*, void*);

    struct HoDataFwdRoutingInfo
     {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        typedef enum
        {
            INTRALTE,
            INTERRAT2UTRAN
        } RoutingMode;

        RoutingMode routingMode_;
        uint16_t lcId_;
        uint16_t flowId_;
        uint32_t targetIp_;
        bool ulGtpTunnelEpPresent_;
        TeIdType ulTeId_;
        bool dlGtpTunnelEpPresent_;
        TeIdType dlTeId_;
        in_addr_t sourceX2uIp_;
        bool targetFlowIdPresent_;
        uint16_t targetFlowId_;
        bool x2nbrInstancePresent_;
        uint16_t x2nbrInstance_;

        HoDataFwdRoutingInfo()
        {
            memset(this, 0, sizeof(HoDataFwdRoutingInfo));
        }

        void debugDump(std::string& outString) const;
     };

    struct HoDataFwdRoutingInfoList
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint8_t numOfInfo_;
        HoDataFwdRoutingInfo hoDataFwdRoutingInfo_[MAX_PDCP_INFO_PER_REQUEST];

        HoDataFwdRoutingInfoList()
     {
            memset(this, 0, sizeof(HoDataFwdRoutingInfoList));
     }

        void debugDump(std::string& outString) const;
    };

    struct PdcpSnStatusInfo
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint16_t lcId_;
        uint16_t flowId_;
        uint16_t dlNextTxSn_;
        uint16_t ulFms_;  // uplink First Missing Sequence Number
        uint32_t dlHfn_;
        uint32_t ulHfn_;
        uint8_t ulBitstringPresent_;
        uint8_t ulSnBitstring_[MAX_NUM_MISSING_SN / 8];
        BackhaulReturnCode result_;

        PdcpSnStatusInfo()
        {
            memset(this, 0, sizeof(PdcpSnStatusInfo));
            result_ = BackhaulRC::SUCCESS;
        }

        void debugDump(std::string& outString) const;
    };

    struct PdcpSnStatusInfoList
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint8_t numOfPdcpSnStatusInfo_;
        PdcpSnStatusInfo pdcpSnStatusInfo_[MAX_PDCP_INFO_PER_REQUEST];

        PdcpSnStatusInfoList()
        {
            memset(this, 0, sizeof(PdcpSnStatusInfoList));
        }

        void debugDump(std::string& outString) const;
    };

    struct PdcpIndication
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint16_t flowId_;
        uint16_t lcId_;
        uint32_t gwIp_;

        PdcpIndication()
        {
            memset(this, 0, sizeof(PdcpIndication));
        }

        void debugDump(std::string& outString) const;
    };

    struct PdcpIndicationRecord
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint8_t numOfPdcpIndRecords_;
        bool isIntraEnb_;

        PdcpIndication pdcpIndication_[MAX_PDCP_INFO_PER_REQUEST];

        PdcpIndicationRecord()
        {
            memset(this, 0, sizeof(PdcpIndicationRecord));
        }

        void debugDump(std::string& outString) const;
    };

    struct GtpuRoutingInfo
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint32_t srcIp;
        uint32_t destIp;
        TeIdType srcTeId;
        TeIdType destTeId;
        BackhaulReturnCode result;
        uint16_t lcId; // To allow mapping results back to request list

        GtpuRoutingInfo()
        {
            memset(this, 0, sizeof(GtpuRoutingInfo));
            result = BackhaulRC::SUCCESS;
        }

        void debugDump(std::string& outString) const;
    };

    typedef struct GtpuRoutingInfoList
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint8_t numRecords;
        GtpuRoutingInfo routingRecords[MAX_GTPU_ROUTING_RECORDS_PER_REQUEST];

        GtpuRoutingInfoList()
        {
            memset(this, 0, sizeof(GtpuRoutingInfoList));
        };

        void debugDump(std::string& outString) const;
    } GtpuRoutingInfoList;

    struct PathSwitchInfo
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.

        uint16_t targetFlowId_;
        TeIdType dlTeId_;

        PathSwitchInfo() : targetFlowId_(0), dlTeId_(0) {}
        void debugDump(std::string& outString) const;
    };

    struct PathSwitchInfoList
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.

        uint8_t numRecords_;
        PathSwitchInfo pathSwitchRecords_[MAX_GTPU_ROUTING_RECORDS_PER_REQUEST];

        PathSwitchInfoList()
        {
            memset(this, 0, sizeof(PathSwitchInfoList));
        };

        void debugDump(std::string& outString) const;
    };

    ///@todo ********** Deprecated ********** replaced by BackhaulReturnCode
    typedef enum
    {
        GTPUOK,
        FAIL_INVALID_PARAMS,                // Passed in parameters are incorrect
        FAIL_TABLE_SATURATED,               // Routing table is full
        FAIL_NO_MATCH,                      // Can't find resource
        FAIL                                // ONLY USE IF *IMPOSSIBLE* TO FIGURE OUT PROBLEM
    } GtpuReturnCode;

    typedef struct RohcProfile
    {
        bool profile0x0001;
        bool profile0x0002;
        bool profile0x0003;
        bool profile0x0004;
        bool profile0x0006;
        bool profile0x0101;
        bool profile0x0102;
        bool profile0x0103;
        bool profile0x0104;
    } RohcProfile;

    typedef enum RohcContextSpace
    {
        ROHC_CTX_SPACE_INVALID,
        ROHC_CTX_SPACE_LARGE,
        ROHC_CTX_SPACE_SMALL
    } RohcContextSpace;

    typedef struct RohcInfo
    {
        bool isHeaderCompressionEnabled;
        uint16_t maxCid;
        RohcContextSpace ctxSpace;
        RohcProfile profile;
    } RohcInfo;

    struct UeContextInfo
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        CellProcessIdType  cellProcessIndex;
        GblCellIdType      glbCellId;
        ContextIdType      ueContextId;
        bool               isLcIdPresent;
        uint16_t           lcId;

        UeContextInfo()
        {
            memset(this, 0, sizeof(UeContextInfo));
        }

        void debugDump(std::string& outString) const;
    };

    typedef enum
    {
        L2OK,
        L2OK_BUT_CIPHER_SN_EXHAUSTION_HWM,  // Cipher sn exhaustion high water mark reached.
        CAPABILITY_NOT_SUPPORTED,           // Not implemented, not supported
        MEMORY_ALLOCATION_FAILURE,          // typically new fail
        RESOURCE_NOT_INITIALIZED,           // Not initialized
        RESOURCE_NOT_AVAILABLE,             // Not available, not right state to perform
        RESOURCE_NOT_FOUND,                 // Can't find resource
        RESOURCE_ALREADY_EXISTS,            // Can't allocate a duplicate resource
        MAXIMUM_RESOURCES_ALREADY_IN_USE,   // Can't allocate any more resources
        UNEXPECTED_NULL_POINTER,            // Null pointer
        UNEXPECTED_DATA_VALUE_ENCOUNTERED,  // Encounter a bad value
        UNEXPECTED_DATA_VALUE_PASSED_IN,    // Bad value passed into method
        INTEGRITY_PROTECTION_FAILURE,       // Integrity Protection failed.
        CIPHER_SN_EXHAUSTION,               // Cipher Sequence Number Exhaustion.
        INVALID_CONFIGURATION_DATA,         // Bad configuration data/data mismatch
        REQUEST_NOT_VALID_FOR_STATE,        // Can't process due to state it is in
        INVALID_INTERNAL_STATE,             // Internal state is not correct
        INVALID_STATE,                      // Customer visible state not correct
        NOT_VALID_FOR_FLOW,                 // Request invalid for type of flow selected
        INTERNAL_FAILURE,                   // ONLY USE IF *IMPOSSIBLE* TO FIGURE OUT PROBLEM
        SRB_SETUP_FAILED,                   // Indicate that SRB setup failed
        RB_LIST_RELEASE_PARTIAL_FAILURE,    // Indicate that one or more RB in the release list failed on the L2 release
        RB_LIST_MODIFY_PARTIAL_FAILURE,     // Indicate that one or more RB in the modify list failed on the L2 modify
        RB_LIST_SETUP_PARTIAL_FAILURE,      // Indicate that one or more RB in the setup list failed the L2 setup
        RB_L2_RSP_TIMEOUT,                  // Indicate a timeout happened while waiting for a L2 RB response (setup/modify/release)
        UNSUPPORTED_FUNCTIONALITY,          // Functionality invoked is unsupported
        OBSOLETE_FUNCTIONALITY,             // Functionality invoked is obsolete
        CAC_REJECT_MAC_NON_GBR_REJECTED_CONGESTION, // Call Admission Control Reject MAC Non-GBR rejected for conjestion
        CAC_REJECT_MAC_GBR_REJECTED_CONGESTION_PRB_USAGE, // Call Admission Control Reject MAC GBR rejected for conjestion PRB usage
        RB_LIST_SETUP_ALL_FAILURE  // Indicate that all RBs in the setup list failed the L2 setup
    } L2ReturnCode;

    enum IntegrityProtAlgorithm
    {
        INTEGRITY_PROTECTION_EIA0 = 0, // NULL
        INTEGRITY_PROTECTION_EIA1 = 1, // 3G SNOW
        INTEGRITY_PROTECTION_EIA2 = 2, // AES
        INTEGRITY_PROTECTION_EIA3 = 3, // ZUC
        MAX_INTEGRITY_PROTECTION_ALGORITHM
    };

    enum CipheringAlgorithm
    {
        CIPHERING_EEA0 = 0, // NULL
        CIPHERING_EEA1 = 1, // 3G-SNOW
        CIPHERING_EEA2 = 2, // AES
        CIPHERING_EEA3 = 3, // ZUC
        MAX_CIPHERING_ALGORITHM
    };

    const uint8_t KEY_ENB_SIZE = 32;  // 256 bits
    const uint8_t NEXT_HOP_SIZE = 32;  // 256 bits
    const uint8_t KEY_RRC_INT = 16;     // 128 bits
    const uint8_t KEY_RRC_ENC = 16;     // 128 bits
    const uint8_t KEY_UP_ENC = 16;      // 128 bits

    // The following two constants which are used by both Call-P and PDCP.
    const uint8_t PDCP_SRB_HEADER_SIZE = 1;

    const uint8_t PDCP_MACI_SIZE = 4;

    const uint8_t PDCP_PDU_SRB_OVERHEAD = PDCP_SRB_HEADER_SIZE + PDCP_MACI_SIZE;

    const uint8_t INVALID_SRB_PDCP_SN = 0xff;

    struct L2PdcpCipherParams
    {
        L2PdcpCipherParams()
        {
            memset(this, 0, sizeof(L2PdcpCipherParams));
        };

        L2PdcpCipherParams(uint8_t inRbId, CipheringAlgorithm inAlg, const uint8_t* inKey):
          rbId(inRbId),
          alg(inAlg)
        {
            memcpy(key, inKey, KEY_RRC_ENC);
        };

        uint8_t rbId;
        CipheringAlgorithm alg;
        uint8_t key[KEY_RRC_ENC];

    };

    struct L2PdcpIntegrityParams
    {
        L2PdcpIntegrityParams()
        {
            memset(this, 0, sizeof(L2PdcpIntegrityParams));
        };

        L2PdcpIntegrityParams(uint8_t inRbId, IntegrityProtAlgorithm inAlg, const uint8_t* inKey):
          rbId(inRbId),
          alg(inAlg)
        {
            memcpy(key, inKey, KEY_RRC_INT);
        };

        uint8_t rbId;
        IntegrityProtAlgorithm alg;
        uint8_t key[KEY_RRC_INT];
    };

    struct L2UlPdcpStatusInfo
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint8_t lcId_;

        uint8_t numOfMissingPdcpPdu_;
        uint16_t sn_[MAX_NUM_OF_MISSING_PDU];

        void debugDump(std::string& outString) const;
    };

    struct L2DlPdcpStatusInfo
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint8_t lcId_;
        uint16_t nextpdcpSn_;

        void debugDump(std::string& outString) const;
    };

    struct L2PdcpSnStatus
    {
        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.
        uint8_t nbrDlPdcpInfo_;
        L2DlPdcpStatusInfo dlPdcpStatusInfo_[MAX_EPS_BEARER_NUM];

        uint8_t nbrUlPdcpInfo_;
        L2UlPdcpStatusInfo ulPdcpStatusInfo_[MAX_EPS_BEARER_NUM];

        void debugDump(std::string& outString) const;
    };


    typedef struct PrachTimeFrequencyResourceInd
    {
        uint16_t timeInd;
        uint16_t frequencyInd;
    } PrachTimeFrequencyResourceInd;

    typedef enum PowerStepSize
    {
        DB0 = 0,
        DB3 = 1,
        DB6 = 2
    } PowerStepSize;

    typedef struct PrachPreambleTransmitPower
    {
        int16_t initialPreambleTransmitPower;
        PowerStepSize preambleTransmitPowerStepSize;
    } PrachPreambleTransmitPower;



    typedef struct RachInfo
    {
        bool endTimeDedicatedPreamblePresent;
        uint8_t rachRootSeqIndex;
        uint8_t cyclicShiftZone;
        PrachTimeFrequencyResourceInd prachTimeFrequencyResourceInd;
        PrachPreambleTransmitPower prachPreambleTransmitPower;
        uint8_t endTimeDedicatedPreamble;
    } RachInfo;


    typedef enum SrsBandwidth
    {
        srsb44 = 0,
        srsb48 = 1
    } SrsBandwidth;

    typedef enum SrsStartFrequency
    {
        sf1 = 0,
        sf3 = 1
    } SrsStartFrequency;

    typedef struct SoundingRsInfo
    {
        SrsBandwidth srsBandwidth;
        SrsStartFrequency startFrequency;
        uint16_t subFrameOffset;
        uint16_t transmissionComb;
        uint16_t cyclicShift;
    } SoundingRsInfo;


    typedef enum PucchFrequencyDomainResources
    {
        fdr0 = 0,
        fdr1 = 1,
        fdr2 = 2,
        fdr47 = 3,
        fdr48 = 4,
        fdr49 = 5
    } PucchFrequencyDomainResources;

    typedef enum PucchSubframeOffset
    {
        wcsfo0 = 0,
        wcsfo5 = 1
    } PucchSubframeOffset;

#define PUCCH_NUMBER_OF_ALLOWED_SUB_BANDS 9

    typedef struct PucchInfo
    {
        uint16_t cqi_reportMode;
        PucchFrequencyDomainResources frequencyDomainResources;
        uint16_t cyclicShift;
        uint16_t cqi_period;
        PucchSubframeOffset cqi_subframeOffset;

        /// Used to inform UE which sub-bands it should report CQI when not
        /// all the sub-bands can be used by the UE.
        /// Generally, the DL FFR bandwidth partition is controlled by another
        /// configurable para named "DL_FFR_Bandwidth_Partition". In the case of FFR,
        /// (Fractional Frequency Reuse) "Allowed sub-bands" should be configured
        /// according to the setting of "DL_FFR_Bandwidth_Partition". If semantic
        /// check is performed for FFR, the check should be against the para
        /// "DL_FFR_Bandwidth_Partition".
        /// Bitmap is completely settable (refer to DL_FFR_BANDWIDTH_PARTION for the
        /// exact setting.)
        /// Bitmap size is defined by PUCCH_NUMBER_OF_ALLOWED_SUB_BANDS
        /// (Should we refactor to use bitset<> instead?)
        uint16_t allowedSubBandsBitmap;
        uint16_t numberOfSubBandsReport;
    } PucchInfo;

    struct TransportLayerAddressArray
    {
        uint8_t address[transportLayerAddressSize_c];
    };

    struct TransportLayerAddress
    {
        uint8_t lengthInOctets;
        TransportLayerAddressArray data;
    };

    //The NasType is used for eNB internal testing only.
    typedef enum NasType
    {
        NO_NAS,
        ATTACH_REQUEST = 1,
        ATTACH_ACCEPT,
        ATTACH_COMPLETE,
        SERVICE_REQUEST,
        TAU_REQUEST,
        TAU_ACCEPT,
        TAU_COMPLETE,
        IDENTITY_REQUEST,
        IDENTITY_RESPONSE,
        AUTHENTICATION_REQUEST,
        AUTHENTICATION_RESPONSE,
        SECURITY_MODE_COMMAND,
        SECURITY_MODE_COMPLETE
    } NasType;

    // This type is used to indicate the cellbarred status
    // which is part of Sib1.CellAccessRelatedInformation Struture
    typedef enum CellBarredType
    {
        BARRED,
        NOT_BARRED
    } CellBarredType;

    //This is an internal reason code stroed in the UeClass. It maps the reason code from
    //S1 message and callp procedures to OM reason code.
    typedef enum UeContextReleaseReason
    {
        CONTEXT_REL_NORMAL,
        CONTEXT_REL_NO_TRB,
        CONTEXT_REL_RB_INACTIVE,
        CONTEXT_REL_UE_UNREACHABLE,
        CONTEXT_REL_RESET,
        CONTEXT_REL_GTPU_ERROR_INDICATION,
        CONTEXT_REL_SN_EXHAUSTION,
        CONTEXT_REL_UE_MIGRATION,
        CONTEXT_REL_UNSPECIFIED
    } UeContextReleaseReason;

    static const uint8_t tacSize_c = 2;
    struct TrackingAreaCodeType
    {
        uint8_t value[tacSize_c];
        void setAsU16(uint16_t tacUint16)
        {
            // Utility function to convert a uint16_t to big endian byte string
            // (network order).
            value[0]= 0xFF & (tacUint16 >> 8);
            value[1]= 0xFF & (tacUint16);
        }

        uint16_t getAsU16()const
        {
          return (static_cast<uint16_t>(value[0])* 0x10 + value[1]);
        }
    };

    typedef struct X2UPeerMacAddr
    {
        bool isAddrValid;
        uint8_t macAddr[6];
    } X2UPeerMacAddr;



    //#############################################################################################
    // Flow configuration parameters
    //#############################################################################################

    enum BearerAsymmetryIndicator
    {
        SYMMETRIC_BIDIRECTIONAL = 0,
        ASYMMETRIC_UNIDIRECTIONAL_DOWNLINK = 1,
        ASYMMETRIC_UNIDIRECTIONAL_UPLINK = 2,
        ASYMMETRIC_BIDIRECTIONAL = 3
    };

    enum RlcFlowConfigurationChoice
    {
        FLOW_CONFIGURATION_NOT_SPECIFIED = 0,
        FLOW_AM_CHOSEN = 1,
        FLOW_UM_BI_DIR_CHOSEN = 2,
        FLOW_UM_UNI_DIR_UL_CHOSEN = 3,
        FLOW_UM_UNI_DIR_DL_CHOSEN = 4,
        FLOW_TM_BI_DIR_CHOSEN = 5,       // NOTE: Only used in test code
        FLOW_TM_UNI_DIR_DL_CHOSEN = 6
    };
/*
    enum QciLabel
    {
        QCI_LABEL_1     = 1,
        QCI_LABEL_2     = 2,
        QCI_LABEL_3     = 3,
        QCI_LABEL_4     = 4,
        QCI_LABEL_5     = 5,
        QCI_LABEL_6     = 6,
        QCI_LABEL_7     = 7,
        QCI_LABEL_8     = 8,
        QCI_LABEL_9     = 9,

        QCI_LABEL_UNKNOWN
    };
*/

    enum TrafficType
    {
        Sensitive_Traffic     = 0,
        Non_Sensitive_Traffic = 1
    };

    enum PriorityLevel
    {
        PRIORITY_LEVEL_SPARE = 0,
        PRIORITY_LEVEL_HIGHEST = 1,
        PRIORITY_LEVEL_LOWEST = 14,
        NO_PRIORITY = 15,
    };

    enum PreEmptionCapability
    {
        SHALL_NOT_TRIGGER_PREEMPTION = 0,
        MAY_TRIGGER_PREEMPTION = 1
    };

    enum PreEmptionVulnerability
    {
        NOT_PREEMPTABLE = 0,
        PREEMPTABLE = 1
    };

    enum QueuingAllowed
    {
        QUEUEING_NOT_ALLOWED = 0,
        QUEUEING_ALLOWED = 1
    };

    typedef uint64_t MaxBitRate;
    typedef uint64_t GuaranteedBitRate;

    // Contains information as to maximum BIT rate for the uplink and
    // downlink directions.
    struct MaxBitRateInformation
    {
        MaxBitRate downlinkBitRate;
        MaxBitRate uplinkBitRate;
    };

    // Contains information as to Guaranteed BIT rate for the uplink and
    // downlink directions.
    struct GuaranteedBitRateInformation
    {
        GuaranteedBitRate downlinkBitRate;
        GuaranteedBitRate uplinkBitRate;
    };

    /// @note: Not supported in R2.0.
    struct AllocationOrRetentionPriority
    {
        PriorityLevel priorityLevel;
        PreEmptionCapability preEmptionCapability;
        PreEmptionVulnerability preEmptionVulnerability;
        QueuingAllowed queuingAllowed;
    };

    /// (F)ield (E)num macro used to define an index for each field name in a class so they are usable as indexes
    /// to arrays in a consistent manner across the system
#define FE(X, Y) X::FEnum_ ## X ## _ ## Y
#define FE3(X, Y, Z) X::FEnum_ ## X ## _ ## Y ## _ ## Z

    /// FE (D)eclaration used to declare field enums in the class (need to remove class prefix from FE)
#define FED(X, Y) FEnum_ ## X ## _ ## Y
#define FED3(X, Y, Z) FEnum_ ## X ## _ ## Y ## _ ## Z

    /// Macro to turn name in(T)o a (S)tring
#define TS(X) #X

    ///##########################################################################################
    /// Flow parameter container classes
    ///
    /// An attempt has been made to group parameters in a class based on protocol layer, where it
    /// made sense.
    ///
    /// L2UeRbParameters: grouping of parameters shared by all flows or more than one flow.
    /// L2FlowRbParameters: grouping of parameters shared by more than one protocol layer for a flow
    /// L2PdcpRbParameters: grouping of Pdcp related parameters for a flow
    /// L2RlcRbParameters: grouping of Rlc related parameters for a flow
    /// L2MacRbParameters: grouping of Mac related parameters for a flow
    ///
    /// L2RbConfigOutInfo: This container class includes return codes from various protocol
    ///                    layers in reponse to callp configuration requets.
    ///                    Return codes must be checked by callp following a request.
    ///
    /// L2UeFlowConfigInfoContainer: A container of containers, is passed to L2Cell when
    ///   requesting an SRB or DRB flow be created. Includes a pointer to each of the
    ///   parameter container classes above as well as an instance of L2RbConfigOutInfo.
    ///
    /// NOTE:
    /// If the database schema (Excel spreadsheet) calls for a certain value to be set to infinity,
    /// the value should be set to the maximum unsigned integer the type used can hold. This is
    /// probably most easily done by assigning the unsigned integer the value ~0 - in C++ this is
    /// the one's complement of 0 (i.e. all 1's).
    ///
    /// NOTE:
    /// All fields whose values were obtained from confd database include the path to the
    /// element in the comments. If the database path is missing, this means the field was
    /// provided by callP or Mme via callp but NOT obtained from confd database by callp.
    ///
    /// Class field names, where the field is obtained from the database, are shortened versions
    /// of the database element name (minus the '-', and some values, such as downlink and uplink
    /// shortened to Dl and Ul). In other cases, to distinguish a group of related fields, a
    /// common prefix has been added (ex. chnl for the logical-channel-config parameters).
    /// For example: prioritized-bit-rate becomes chnlPrioritizedBitRate_
    ///
    ///##########################################################################################

    ///------------------------------------------------------------------------------------------
    /// L2UeRbParameters to contain parameters applicable at the UE level (ex crnti)
    /// or across all or multiple flows belonging to the UE (ex. aggregate bitrate for non-GBR flows)
    ///
    /// @todo Finalize layer ownership and move parameters to different container as required.
    ///
    ///------------------------------------------------------------------------------------------
    class L2UeRbParameters
    {
     public:
        L2UeRbParameters() :
        cellInstance_(0),
        cellIdWithinEnb_(0),
        crnti_(0),
        haveMmeQosValues_(false),
        haveDbQosValues_(false),
        useAMBR_(false),
        ueAggregateMaximumBitRateDownlink_(5000000),
        ueAggregateMaximumBitRateUplink_(2000000)
        {}

        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.

        //////////////////////////////////////////////////////////////////////////////
        ///
        /// @brief Debug information is added to the specified string. The caller can
        ///        output the string to display the information.
        ///
        /// @param[out] outString - string containing the debug info.
        ///
        /// @returns - void
        ///
        //////////////////////////////////////////////////////////////////////////////
        void debugDump(std::string& outString) const;

        ///***** IMPORTANT *****
        /// If you add or delete any fields in the class, you must update the enum below as well.
        /// The enums are used to initialize configuration table entries in the
        /// initializeL2UeRbParamTableEntries() method. The table entries are used in the output of
        /// of configuration information.
        /// Therefore, if you add, delete or modify any fields in this class, you must also update
        /// the initializeL2UeRbParamTableEntries() method appropriately.
        /// You many also need to update the debugDump_FlowConfig() method and the corresponding
        /// entries in the L2Cell class (for example you add a new print type).
        enum {
            FED(L2UeRbParameters, cellInstance_),
            FED(L2UeRbParameters, cellIdWithinEnb_),
            FED(L2UeRbParameters, crnti_),
            FED(L2UeRbParameters, haveMmeQosValues_),
            FED(L2UeRbParameters, haveDbQosValues_),
            FED(L2UeRbParameters, ueAggregateMaximumBitRateDownlink_),
            FED(L2UeRbParameters, ueAggregateMaximumBitRateUplink_),
            UE_RB_PARAM_TABLE_ENTRIES
        };

        /// Cell instance, from 1 to 9 (R2.0)
        uint16_t                             cellInstance_;

        /// Cell Id within eNB, from 1 to 255
        uint16_t                             cellIdWithinEnb_;

        CrntiType                           crnti_;

        /// Qos flags

        /// Two flags indicating which version of Qos parameters are being used
        /// If haveMmeQosValues_ is true, then the parameters passed by Mme to callP have been
        /// passed down to L2 without modification.
        /// If haveDbQosValues_ is true, then the parameters passed by Mme have been overridden by
        /// callp, which has obtained values from the database to pass down to L2.
        /// If both flags are false, then no Qos values have been passed down to L2 and the Qos
        /// parameters are ignored.
        bool                                haveMmeQosValues_;
        bool                                haveDbQosValues_;

        /// Qos values

        ///indicator for using the supplied AMBR
        bool                                useAMBR_;

        /// ... Max Aggregate Bit rate UL & DL for all non-Guaranteed Bit Rate flows
        ///     /services/cell/radio-bearer-type/ue-config/ue-aggregate-maximum-bitrate/
        MaxBitRate                          ueAggregateMaximumBitRateDownlink_;
        MaxBitRate                          ueAggregateMaximumBitRateUplink_;
    };

    ///------------------------------------------------------------------------------------------
    /// L2SibMibUpdateParameters to contain parameters for L2 use in SibMibUpdate
    ///------------------------------------------------------------------------------------------

    ///------------------------------------------------------------------------------------------
    /// L2SibMibUpdateParameters to contain parameters for L2 use in SibMibUpdate
    ///------------------------------------------------------------------------------------------
    class L2SibCfgUpdateParameters
    {
    public:
        L2SibCfgUpdateParameters():
            groupAssignmentPusch_(0),
            modificationPeriodCoeff_(0),
            pb_(0),
            raResponseWindowSize_(0),
            macContentionResolutionTimer_(0),
            preambleInitialReceivedTargetPower_(0),
            prachFrequencyOffset_(0),
            messagePowerOffsetGroupB_(0),
            enable64Qam_(0),
            groupHoppingEnabled_(0),
            sequenceHoppingEnabled_(0),
            maxHarqMsg3Tx_(0)
        {}

        bool operator!= (const L2SibCfgUpdateParameters& rhs) const;
        bool operator== (const L2SibCfgUpdateParameters& rhs) const;

        L2SibCfgUpdateParameters& operator=(const L2SibCfgUpdateParameters &rhs);

        uint16_t groupAssignmentPusch_;                  // /services/cell/phy-ul/group-assignment-pusch
        uint8_t modificationPeriodCoeff_;                // /services/cell/idle-drx/modification-period-coeff
        uint8_t pb_;                                     // /services/cell/power-control/p-b
        uint8_t raResponseWindowSize_;                   // /services/cell/prach/ra-response-window-size
        uint8_t macContentionResolutionTimer_;           // /services/cell/prach/mac-contention-resolution-timer
        int16_t preambleInitialReceivedTargetPower_;     // /services/cell/prach/preamble-initial-received-target-power
        uint8_t prachFrequencyOffset_;                   // /services/cell/prach/prach-freq-offset
        uint8_t messagePowerOffsetGroupB_;               // /services/cell/prach/message-power-offset-group-b
        uint8_t enable64Qam_;                               // /services/cell/phy-ul/enable-64-qam
        uint8_t groupHoppingEnabled_;                       // /services/cell/phy-ul/group-hopping-enabled
        uint8_t sequenceHoppingEnabled_;                    // /services/cell/phy-ul/sequence-hopping-enabled
        uint16_t maxHarqMsg3Tx_;                         // /services/cell/prach/max-harq-msg3-tx
    };

    ///------------------------------------------------------------------------------------------
    /// L2FlowRbParameters contains parameters used across more than one protocol layer in a flow.
    ///
    /// @todo Finalize layer ownership and move parameters to different container as required.
    ///
    ///------------------------------------------------------------------------------------------
    class L2FlowRbParameters
    {
    public:
        L2FlowRbParameters() :
            saeBearerMaximumBitrateDl_(512000),
            saeBearerMaximumBitrateUl_(512000),
            saeBearerGuaranteedBitrateDl_(512000),
            saeBearerGuaranteedBitrateUl_(512000),
            lcId_(~0),
            originalQciLabel_(QCI_LABEL_UNKNOWN),
            qciLabel_(QCI_LABEL_UNKNOWN),
            packetDelayBudget_(100),
            maxJitter_(100),
            chnlPriority_(9),
            chnlLogicalChannelGroup_(4),
            chnlPrioritizedBitRate_(256),
            chnlBucketSizeDuration_(100),
            packetErrorLossRate_(2),
            flowId_(~0),
            dbConfigOverride_(false),
            logicalChannelConfigDefaulted_(true)
        {}

        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.

        //////////////////////////////////////////////////////////////////////////////
        ///
        /// @brief Debug information is added to the specified string. The caller can
        ///        output the string to display the information.
        ///
        /// @param[out] outString - string containing the debug info.
        ///
        /// @returns - void
        ///
        //////////////////////////////////////////////////////////////////////////////
        void debugDump(std::string& outString) const;


        ///***** IMPORTANT *****
        /// If you add or delete any fields in the class, you must update the enum below as well.
        /// The enums are used to initialize configuration table entries in the
        /// initializeL2FlowRbParamTableEntries() method. The table entries are used in the output of
        /// of configuration information.
        /// Therefore, if you add, delete or modify any fields in this class, you must also update
        /// the initializeL2FlowRbParamTableEntries() method appropriately.
        /// You many also need to update the debugDump_FlowConfig() method and the corresponding
        /// entries in the L2Cell class (for example you add a new print type).
        enum {
            FED(L2FlowRbParameters, flowId_),
            FED(L2FlowRbParameters, lcId_),
            FED(L2FlowRbParameters, qciLabel_),
            FED(L2FlowRbParameters, originalQciLabel_),
            FED(L2FlowRbParameters, saeBearerMaximumBitrateDl_),
            FED(L2FlowRbParameters, saeBearerMaximumBitrateUl_),
            FED(L2FlowRbParameters, saeBearerGuaranteedBitrateDl_),
            FED(L2FlowRbParameters, saeBearerGuaranteedBitrateUl_),
            FED(L2FlowRbParameters, dbConfigOverride_),
            FED(L2FlowRbParameters, packetDelayBudget_),
            FED(L2FlowRbParameters, maxJitter_),
            FED(L2FlowRbParameters, packetErrorLossRate_),
            FED(L2FlowRbParameters, logicalChannelConfigDefaulted_),
            FED(L2FlowRbParameters, chnlPriority_),
            FED(L2FlowRbParameters, chnlPrioritizedBitRate_),
            FED(L2FlowRbParameters, chnlBucketSizeDuration_),
            FED(L2FlowRbParameters, chnlLogicalChannelGroup_),
            FLOW_RB_PARAM_TABLE_ENTRIES
        };

        /// These values are normally signalled by MME, but may be overridden with database values.
        /// They are used on BH for rate control, but are also referenced by Mac when making
        /// scheduling decisions.
        /// /services/cell/radio-bearer-type/drb-qci-1/qos-config/gbr-qos-information/
        uint64_t                            saeBearerMaximumBitrateDl_;
        uint64_t                            saeBearerMaximumBitrateUl_;
        uint64_t                            saeBearerGuaranteedBitrateDl_;
        uint64_t                            saeBearerGuaranteedBitrateUl_;

        /// As per standard, only one lc Id for UL and DL, and it is 16 bit unsigned int.
        uint16_t                            lcId_;

        /// The original Qci Label requested by the UE if it is not the same as the one actually
        /// used by callP. If the UE requested a Qci label not supported by Nortel's eNB, callp
        /// may substitute with one that is. In this case, originalQciLabel_ will contain the
        /// original Ue requested value.
        /// If no Qci label override has been done by callp, this will be set to QCI_LABEL_UNKNOWN
        uint8_t                             originalQciLabel_;

        /// R2.0 QoS Control Index
        /// Valide values are defined by enum QciLabel
        /// Matches [n] in /services/cell/radio-bearer-type/drb-qci-[n]/
        uint8_t                             qciLabel_;

        /// @todo - add descriptive comment on where these values are used
        /// /services/cell/radio-bearer-type/drb-qci-[n]/qos/
        /// Where [n] matches 1, 8 or 9
        uint16_t                            packetDelayBudget_;
        uint16_t                            maxJitter_;

        /// UL channel scheduling parameters
        /// /services/cell/radio-bearer-type/[rb type]/logical-channel-config/ul-specific-parameters/
        /// Present for all rb types, including srb-0.
        uint8_t                             chnlPriority_;
        uint8_t                             chnlLogicalChannelGroup_;
        uint16_t                            chnlPrioritizedBitRate_;
        uint16_t                            chnlBucketSizeDuration_;

        /// @todo - add descriptive comment on where these values are used
        /// /services/cell/radio-bearer-type/drb-qci-[n]/qos/
        /// Where [n] matches 1, 8 or 9
        //regulated for the memory base
        uint8_t                             packetErrorLossRate_;

        /// Assigned by callP for DRBs, assigned by Rlc for SRBs
        FlowIdType                          flowId_;

        bool                                dbConfigOverride_;

        /// If true, indicates logical channel config info is explicitly sent to Ue. Otherwise,
        /// default values are used.
        /// /services/cell/radio-bearer-type/[rb type]/logical-channel-config/
        /// Where [rb type] corresponds to all except srb-0.
        bool                                logicalChannelConfigDefaulted_;

    };

    ///------------------------------------------------------------------------------------------
    /// PDCP related parameters received from callP.
    ///
    /// @todo Finalize layer ownership and move parameters to different container as required.
    ///
    ///------------------------------------------------------------------------------------------
    class L2PdcpRbParameters
    {
    public:
        typedef enum
        {
            INITIAL_RB_SETUP,
            RB_RESERVATION_INTER_ENB,
            RB_RESERVATION_INTRA_ENB,
            RB_RESERVATION_INTERRAT_UTRAN
        } FlowSetupMode;

        L2PdcpRbParameters() :
        x2nbrInstance_(0),
        gwIp_(0),
        srcIp_(0),
        ulTeId_(0),
        dlTeId_(0),
        dlHoDataFwdTeId_(0),
        ulHoDataFwdTeId_(0),
        spare1_(0),
        spare2_(0),
        maxSduQueueSize_(768),
        discardTimer_(1500),
        lcId_(MAX_DRB_LCID+1),
        discardStartLevel_(10),
        discardAllLevel_(10),
        cellInstance_(0),
        macProcessorId_(0),
        pdcpSnSize_(12),
        flowSetupMode_(static_cast<uint8_t>(INITIAL_RB_SETUP)),
        result_(BackhaulRC::PDCP_FAIL),
        statusReportRequired_(true),
        headerCompressionEnabled_(false),
        x2nbrInstancePresent_(false),
        dlHoDataFwdTeIdPresent_(false),
        ulHoDataFwdTeIdPresent_(false)
        {
        }

        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.

        //////////////////////////////////////////////////////////////////////////////
        ///
        /// @brief Debug information is added to the specified string. The caller can
        ///        output the string to display the information.
        ///
        /// @param[out] outString - string containing the debug info.
        ///
        /// @returns - void
        ///
        //////////////////////////////////////////////////////////////////////////////
        void debugDump(std::string& outString) const;

        ///***** IMPORTANT *****
        /// If you add or delete any fields in the class, you must update the enum below as well.
        /// The enums are used to initialize configuration table entries in the
        /// initializeL2PdcpRbParamTableEntries() method. The table entries are used in the output of
        /// of configuration information.
        /// Therefore, if you add, delete or modify any fields in this class, you must also update
        /// the initializeL2PdcpRbParamTableEntries() method appropriately.
        /// You many also need to update the debugDump_FlowConfig() method and the corresponding
        /// entries in the L2Cell class (for example you add a new print type).
        enum {
            FED(L2PdcpRbParameters, cellInstance_),
            FED(L2PdcpRbParameters, macProcessorId_),
            FED(L2PdcpRbParameters, x2nbrInstancePresent_),
            FED(L2PdcpRbParameters, x2nbrInstance_),
            FED(L2PdcpRbParameters, result_),
            FED(L2PdcpRbParameters, lcId_),
            FED(L2PdcpRbParameters, gwIp_),
            FED(L2PdcpRbParameters, srcIp_),
            FED(L2PdcpRbParameters, ulTeId_),
            FED(L2PdcpRbParameters, dlTeId_),
            FED(L2PdcpRbParameters, flowSetupMode_),
            FED(L2PdcpRbParameters, dlHoDataFwdTeIdPresent_),
            FED(L2PdcpRbParameters, ulHoDataFwdTeIdPresent_),
            FED(L2PdcpRbParameters, dlHoDataFwdTeId_),
            FED(L2PdcpRbParameters, ulHoDataFwdTeId_),
            FED3(L2PdcpRbParameters, cipherParams_, rbId),
            FED3(L2PdcpRbParameters, cipherParams_, alg),
            FED3(L2PdcpRbParameters, cipherParams_, key),
            FED(L2PdcpRbParameters, maxSduQueueSize_),
            FED(L2PdcpRbParameters, discardTimer_),
            FED(L2PdcpRbParameters, statusReportRequired_),
            FED(L2PdcpRbParameters, pdcpSnSize_),
            FED(L2PdcpRbParameters, headerCompressionEnabled_),
            FED(L2PdcpRbParameters, spare1_),
            FED(L2PdcpRbParameters, spare2_),
            FED(L2PdcpRbParameters, discardStartLevel_),
            FED(L2PdcpRbParameters, discardAllLevel_),
            PDCP_RB_PARAM_TABLE_ENTRIES
        };

        ///******************* start of non configurable data *******************

        /// X2 neighbor instance ID (/services/nbr-enb-config[1-32])
        uint32_t                            x2nbrInstance_;

        /// Note: Both these IP addresses should be in host order.
        /// @todo - Need to verify with callP team that they will deliver in host order.
        /// Gateway IP address
        uint32_t                            gwIp_;
        /// Source IP address
        /// @todo - find out from callP which source address
        uint32_t                            srcIp_;

        /// Uplink tunnel end point ID (GW)
        uint32_t                            ulTeId_;
        /// Downlink tunnel end point Id assigned to GTPU tunnel end point for flow on BH processor
        uint32_t                            dlTeId_;

        /// Downlink HoDataFwd TEID
        uint32_t                            dlHoDataFwdTeId_;
        /// Uplink HoDataFwd TEID
        uint32_t                            ulHoDataFwdTeId_;

        ///***************** end of non-configurable data ********************
        /// @todo - add header compression parameters when support added

        /// Spare elements for future use
        /// /services/cell/radio-bearer-type/drb-qci-8/pdcp-config/
        /// where [n] is 1, 8, or 9
        uint32_t                            spare1_;
        uint32_t                            spare2_;

        /// /services/cell/radio-bearer-type/drb-qci-[n]/pdcp-config/
        /// where [n] is 1, 8, or 9 and includes all the following
        /// ... max DL SDU queue size
        uint16_t                            maxSduQueueSize_;
        /// ... discard timer
        uint16_t                            discardTimer_;

        /// To allow mapping results back to request list
        uint16_t                            lcId_;

        /// ... /services/cell/radio-bearer-type/drb-qci-[n]/congestion-control/
        /// where [n] is 1, 8, or 9
        uint16_t                            discardStartLevel_;
        uint16_t                            discardAllLevel_;

        /// Cell instance ID
        uint8_t                            cellInstance_;
        /// MAC processor ID
        uint8_t                            macProcessorId_;

        /// Rlc UM mode only
        /// ... PDCP SN size
        /// ... /services/cell/radio-bearer-type/drb-qci-1/pdcp-config/rlc-um/
        uint8_t                             pdcpSnSize_;

        /// Passed from CallP to PDCP to indicate in which mode the API is invoked.
        uint8_t                             flowSetupMode_;

        /// PDCP DRB Ciphering parameters
        L2PdcpCipherParams                  cipherParams_;

        /// PDCP flow creation status
        BackhaulReturnCode                  result_;

        /// Rlc AM mode only
        /// ... Require sent status report
        ///     /services/cell/radio-bearer-type/drb-qci-[n]/pdcp-config/rlc-am/
        ///     where [n] is 8 or 9
        bool                                statusReportRequired_;

        /// NOTE: currently always false (R2.0) since header compression is not supported
        /// ... /services/cell/radio-bearer-type/drb-qci-[n]/pdcp-config/header-compression/
        /// where [n] is 1, 8, or 9

        /// RoHC parameters
        bool                                headerCompressionEnabled_;

        /// X2 neighbor instance ID present indicator
        bool                                x2nbrInstancePresent_;

        /// HoDataFwd routing info for HO
        /// Downlink HoDataFwd TEID present indicator
        bool                                dlHoDataFwdTeIdPresent_;
        /// Uplink HoDataFwd TEID present indicator
        bool                                ulHoDataFwdTeIdPresent_;
    };

    ///------------------------------------------------------------------------------------------
    /// Parameters obtained from callP and used by Rlc to configure flows
    ///
    /// @todo Finalize layer ownership and move parameters to different container as required.
    ///
    ///------------------------------------------------------------------------------------------
    class L2RlcRbParameters
    {
    public:
        L2RlcRbParameters() :
            spare1_(0),
            spare2_(0),
            maxSduQueueSize_(768),
            tReordering_(40),
            tStatusProhibit_(0),
            tPollRetransmit_(50),
            pollPdu_(~0),
            pollByte_(~0),
            maxRetxThreshold_(4),
            rlcConfigurationChoice_(FLOW_AM_CHOSEN),
            rlcMode_(0), 
            bearerAsymmetryIndicator_(SYMMETRIC_BIDIRECTIONAL),
            ulSnFieldLength_(UM_5BIT_SN_SIZE),
            dlSnFieldLength_(UM_5BIT_SN_SIZE),
            maxDlBitRate_(~0),
            maxUlBitRate_(~0),
            srbHandler_(NULL),
            rlcConfigDefaulted_(false)
         {
         }

        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.

        //////////////////////////////////////////////////////////////////////////////
        ///
        /// @brief Debug information is added to the specified string. The caller can
        ///        output the string to display the information.
        ///
        /// @param[out] outString - string containing the debug info.
        ///
        /// @returns - void
        ///
        //////////////////////////////////////////////////////////////////////////////
        void debugDump(std::string& outString) const;

        ///***** IMPORTANT *****
        /// If you add or delete any fields in the class, you must update the enum below as well.
        /// The enums are used to initialize configuration table entries in the
        /// initializeL2RlcRbParamTableEntries() method. The table entries are used in the output of
        /// of configuration information.
        /// Therefore, if you add, delete or modify any fields in this class, you must also update
        /// the initializeL2RlcRbParamTableEntries() method appropriately.
        /// You many also need to update the debugDump_FlowConfig() method and the corresponding
        /// entries in the L2Cell class (for example you add a new print type).
        enum {
            FED(L2RlcRbParameters, rlcConfigurationChoice_),
            FED(L2RlcRbParameters, rlcMode_),
            FED(L2RlcRbParameters, srbHandler_),
            FED(L2RlcRbParameters, maxSduQueueSize_),
            FED(L2RlcRbParameters, rlcConfigDefaulted_),
            FED(L2RlcRbParameters, bearerAsymmetryIndicator_),
            FED(L2RlcRbParameters, maxDlBitRate_),
            FED(L2RlcRbParameters, maxUlBitRate_),
    //        FED(L2RlcRbParameters, allocOrRetPriorityPresent_),
    //        FED(L2RlcRbParameters, allocOrRetPriorityLevel_),
    //        FED(L2RlcRbParameters, allocOrRetPreEmptionCapability_),
    //        FED(L2RlcRbParameters, allocOrRetPreEmptionVulnerability_),
    //        FED(L2RlcRbParameters, allocOrRetQueuingAllowed_),
            FED(L2RlcRbParameters, tReordering_),
            FED(L2RlcRbParameters, tStatusProhibit_),
            FED(L2RlcRbParameters, tPollRetransmit_),
            FED(L2RlcRbParameters, pollPdu_),
            FED(L2RlcRbParameters, pollByte_),
            FED(L2RlcRbParameters, maxRetxThreshold_),
            FED(L2RlcRbParameters, ulSnFieldLength_),
            FED(L2RlcRbParameters, dlSnFieldLength_),
            FED(L2RlcRbParameters, spare1_),
            FED(L2RlcRbParameters, spare2_),
            RLC_RB_PARAM_TABLE_ENTRIES
        };

        /// Spare attributes for all rb types
        /// /services/cell/radio-bearer-type/[rb type]/rlc-config/
        /// where [rb type] includes all rb types except srb 0 and pcch
        uint32_t                            spare1_;
        uint32_t                            spare2_;

        /// Max Rlc DL SDU queue size
        /// /services/cell/radio-bearer-type/[rb type]/rlc-config/
        /// where [rb type] applies to all flow types
        uint16_t                            maxSduQueueSize_;

        ///###################################################################
        /// NOTE: UL and DL are used here from the signaling to UE perspective which
        ///       is opposite to the eNB RLC is configured.
        ///       Thus, in the database UL from a UE perspective means DL from an eNB perspective.
        ///       UL fields from the database must be put into DL fields in this class
        ///       and vice versa.
        ///###################################################################

        /// Common to AM and UM UL
        /// /services/cell/radio-bearer-type/[rb type]/rlc-config/dl-am/
        /// where [rb type] includes all rb types except srb 0, and pcch
        uint16_t                            tReordering_;

        /// AM - UL
        /// /services/cell/radio-bearer-type/[rb type]/rlc-config/dl-am/
        /// where [rb type] includes all rb types except srb 0, pcch and Qci 1
        uint16_t                            tStatusProhibit_;

        /// AM - DL
        /// Note that when infinity is requested as a value for one of these parameters,
        /// the field should be filled with max uint (in C++, this is ~0 - one's complement of 0)
        /// /services/cell/radio-bearer-type/[rb type]/rlc-config/ul-am/
        /// where [rb type] includes all rb types except srb 0, pcch and Qci 1
        uint16_t                            tPollRetransmit_;
        uint16_t                            pollPdu_;
        uint16_t                            pollByte_;
        uint16_t                            maxRetxThreshold_;

       /// AM Bidirectional, UM Bidirectional, UM Unidirectional UL or DL
        uint8_t                             rlcConfigurationChoice_;

        /// AM, UM or TM
        /// @todo - determine whether we need this or not - is it == rlcConfigurationChoice_
        ///         only issue may be rlcConfigurationChoice_ doesn't include TM mode
        uint8_t                             rlcMode_;

        /// #### From previous interface ####
        /// From callP
        /// @todo - is this field still required ?
        uint8_t                             bearerAsymmetryIndicator_;

        /// UM - UL
        /// /services/cell/radio-bearer-type/drb-qci-1/rlc-config/dl-um/
        uint8_t                             ulSnFieldLength_;

        /// UM - DL
        /// /services/cell/radio-bearer-type/drb-qci-1/rlc-config/ul-um/
        uint8_t                             dlSnFieldLength_;

        /// #### From previous interface ####
        /// Max GBR bitrate
        /// @todo - Determine if callP will still send this down for GBR flows
        ///         Are they the same as /services/cell/radio-bearer-type/drb-qci-1/qos/gbr-qos-information/ ???
        MaxBitRate                          maxDlBitRate_;
        MaxBitRate                          maxUlBitRate_;

        /// CallP's Logical Channel Handler for SRBs
        SignalingFlowMessageHandler *       srbHandler_;

        /// If false, explicit SRB 1 rlc config sent to UE. Otherwise default values used.
        /// /services/cell/radio-bearer-type/srb-1/rlc-config/
        bool                                rlcConfigDefaulted_;
    };

    ///------------------------------------------------------------------------------------------
    /// Parameters obtained from callP and used by Mac to configure flows
    ///
    /// @todo Finalize layer ownership and move parameters to different container as required.
    ///
    ///------------------------------------------------------------------------------------------
    class L2MacRbParameters
    {
    public:
       static const uint32_t INVALID_PF = 0xFFFFFFFF;
       static const uint32_t INVALID_PO = 0xFFFFFFFF;

        // nbValue lookup table based on Paging Cycle T and nB.
        static uint32_t nbValueLookUp [R1::NUM_OF_DEFAULT_PAGING_CYCLE]
                                      [R1::NUM_OF_NB];

        // tValue lookup table based on Paging Cyvle T.
        static uint32_t tValueLookUp [R1::NUM_OF_DEFAULT_PAGING_CYCLE];

        // Ns and Is constant used to define the
        // poLookUp table below.
        static const uint8_t NUM_OF_Ns = 5;
        static const uint8_t NUM_OF_Is = 4;

        // PO look up based on N_s and I_s
        //
        // @ todo
        // Add FDD/TDD as first index and populate
        // the TDD associated PO values along
        // with FDD values when TDD is supported.
         static int poLookUp[NUM_OF_Ns][NUM_OF_Is];

        L2MacRbParameters() :
            dlMaxNumHarqRetx_(5),
            defaultPagingCycle_(R1::DEFAULT_PAGINGCYCLE_RF32),
            nB_(R1::NB_ONE_THIRTY_SECOND_T)
        {}

        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.

        //////////////////////////////////////////////////////////////////////////////
        ///
        /// @brief Debug information is added to the specified string. The caller can
        ///        output the string to display the information.
        ///
        /// @param[out] outString - string containing the debug info.
        ///
        /// @returns - void
        ///
        //////////////////////////////////////////////////////////////////////////////
        void debugDump(std::string& outString) const;

        ///***** IMPORTANT *****
        /// If you add or delete any fields in the class, you must update the enum below as well.
        /// The enums are used to initialize configuration table entries in the
        /// initializeL2MacRbParamTableEntries() method. The table entries are used in the output of
        /// of configuration information.
        /// Therefore, if you add, delete or modify any fields in this class, you must also update
        /// the initializeL2MacRbParamTableEntries() method appropriately.
        /// You many also need to update the debugDump_FlowConfig() method and the corresponding
        /// entries in the L2Cell class (for example you add a new print type).
        enum {
            FED(L2MacRbParameters, dlMaxNumHarqRetx_),
            FED(L2MacRbParameters, defaultPagingCycle_),
            FED(L2MacRbParameters, nB_),
            MAC_RB_PARAM_TABLE_ENTRIES
        };

        /// Max HARQ retransmissions
        /// /services/cell/radio-bearer-type/[rb type]/mac-config/
        /// where [rb type] includes all except srb 0 and pcch
        uint8_t                             dlMaxNumHarqRetx_;

        /// TS 36.331
        ///    PCCH-Config ::=      SEQUENCE {
        ///    defaultPagingCycle     ENUMERATED {
        ///               rf32, rf64, rf128, rf256},
        ///
        ///    nB ENUMERATED {
        ///               fourT, twoT, oneT, halfT, quarterT, oneEighthT,
        ///               oneSixteenthT, oneThirtySecondT}
        ///

        /// These two are broadcast in SIB2.
        /// /services/cell/idle-drx/default-paging-cycle
        uint16_t                            defaultPagingCycle_;
        /// @todo - defined as a string in data model - OAM team needs to convert to numeric value
        /// /services/cell/idle-drx/nb
        uint8_t                             nB_;

    };

    enum printId
    {
        PRINT_UINT8 = 0,
        PRINT_UINT16,
        PRINT_UINT32,
        PRINT_UINT64,
        PRINT_HEX16,
        PRINT_HEX32,
        PRINT_BOOLEAN,
        PRINT_IP,
        PRINT_HEXSTR
    };

    // The below struct is used to defined all the parameters which are needed
    // for creating a flow. The parameters are: UeRb, FlowRb, RlcRb, PdcpRb, MacRb
    // The struct defines the field name for each of the above parameters and
    // also stores the offset value for each of the attributes stored in the parameter
    // table. The printType is a value which is passed to the outputDataByPrintType()
    // so it can decode the value pointed to and output using the string stream.

    struct FlowConfigParameters
    {
        FlowConfigParameters():offset(0), printType(PRINT_UINT8), length(0)
        {};
        string fieldName;
        uint32_t offset;
        enum printId printType;
        uint8_t length;
    };

    class FlowConfigInfo
    {
    public:
        FlowConfigInfo()
        {};

        // Ue Parameters Table
        static FlowConfigParameters ueParamTable_[LteApp::L2UeRbParameters::UE_RB_PARAM_TABLE_ENTRIES];

        // Flow Parameters Table
        static FlowConfigParameters flowParamTable_[LteApp::L2FlowRbParameters::FLOW_RB_PARAM_TABLE_ENTRIES];

        // Pdcp Parameters Table
        static FlowConfigParameters pdcpParamTable_[LteApp::L2PdcpRbParameters::PDCP_RB_PARAM_TABLE_ENTRIES];

        // Rlc Parameters Table
        static FlowConfigParameters rlcParamTable_[LteApp::L2RlcRbParameters::RLC_RB_PARAM_TABLE_ENTRIES];

        // Mac Parameters Table
        static FlowConfigParameters macParamTable_[LteApp::L2MacRbParameters::MAC_RB_PARAM_TABLE_ENTRIES];
    };

    //////////////////////////////////////////////////////////////////////////////
    ///
    /// @brief Initializes the L2UeRbParameters table entries which is used by the
    /// L2Cell class to output the flow configuration via an MDF command
    ///
    /// @param[out] - void
    ///
    /// @returns - void
    ///
    //////////////////////////////////////////////////////////////////////////////
    void initializeL2UeRbParamTableEntries();

    //////////////////////////////////////////////////////////////////////////////
    ///
    /// @brief Initializes the L2FlowRbParameters table entries which is used by the
    /// L2Cell class to output the flow configuration via an MDF command
    ///
    /// @param[out] - void
    ///
    /// @returns - void
    ///
    //////////////////////////////////////////////////////////////////////////////
    void initializeL2FlowRbParamTableEntries();

    //////////////////////////////////////////////////////////////////////////////
    ///
    /// @brief Initializes the L2PdcpRbParameters table entries which is used by the
    /// L2Cell class to output the flow configuration via an MDF command
    ///
    /// @param[out] - void
    ///
    /// @returns - void
    ///
    //////////////////////////////////////////////////////////////////////////////
    void initializeL2PdcpRbParamTableEntries();

    //////////////////////////////////////////////////////////////////////////////
    ///
    /// @brief Initializes the L2RlcRbParameters table entries which is used by the
    /// L2Cell class to output the flow configuration via an MDF command
    ///
    /// @param[out] - void
    ///
    /// @returns - void
    ///
    //////////////////////////////////////////////////////////////////////////////
    void initializeL2RlcRbParamTableEntries();

    //////////////////////////////////////////////////////////////////////////////
    ///
    /// @brief Initializes the L2MacRbParameters table entries which is used by the
    /// L2Cell class to output the flow configuration via an MDF command
    ///
    /// @param[out] - void
    ///
    /// @returns - void
    ///
    //////////////////////////////////////////////////////////////////////////////
    void initializeL2MacRbParamTableEntries();

    //////////////////////////////////////////////////////////////////////////////
    ///
    /// @brief Outputs to an output stream given a pointer to the data, its print type
    /// an output string, and a length (optional)
    ///
    /// @param[in] - data_ptr - pointer to data to be output
    /// @param[in] - printType - the print type of the data
    /// @param[out] - oss - the output stream to which data to be sent in print format
    /// @param[in] - length - optional length (only required for variable length items)
    ///
    /// @returns - void
    ///
    //////////////////////////////////////////////////////////////////////////////
    void outputDataByPrintType(void* data_ptr, uint8_t printType, std::ostream &oss, uint8_t length);

    ///------------------------------------------------------------------------------------------
    /// Output information returned from L2 components
    ///
    /// @todo Finalize layer ownership and move parameters to different container as required.
    ///
    ///------------------------------------------------------------------------------------------
    class L2RbConfigOutInfo
    {
    public:
        L2RbConfigOutInfo() :
            bhReturnCode_(LteApp::BackhaulRC::UNKNOWN_FAILURE),
            rlcReturnCode_(LteApp::INTERNAL_FAILURE),
            flowId_(~0),
            pFlow_(NULL)
        {}

        /// Return code from PDCP layer to flow configuration request from callP
        BackhaulReturnCode                  bhReturnCode_;

        /// Return code from Rlc layer  to flow configuration request from callP
        L2ReturnCode                        rlcReturnCode_;

        /// Callp assigns the flow id for DRBs. Rlc does so for SRBs.
        /// For SRBs, this field gives the value of the flow id assigned by Rlc.
        FlowIdType                          flowId_;

        /// For L2 Rlc flow configuration, a pointer to the flow is returned as a convenience.
        L2Cell_ns::FlowPubIf *              pFlow_;

    };

    ///------------------------------------------------------------------------------------------
    /// A reference to an instance of this class, properly initialized, will be passed to
    /// L2Cell when an SRB or DRB flow needs to be created.
    ///------------------------------------------------------------------------------------------
    class L2UeFlowConfigInfoContainer
    {
    public:
        L2UeFlowConfigInfoContainer(
                L2UeRbParameters &                  l2UeRbParameters,
                L2FlowRbParameters &                l2FlowRbParameters,
                L2PdcpRbParameters &                l2PdcpRbParameters,
                L2RlcRbParameters &                 l2RlcRbParameters,
                L2MacRbParameters &                 l2MacRbParameters)
          : l2UeRbParameters_(l2UeRbParameters),
            l2FlowRbParameters_(l2FlowRbParameters),
            l2PdcpRbParameters_(l2PdcpRbParameters),
            l2RlcRbParameters_(l2RlcRbParameters),
            l2MacRbParameters_(l2MacRbParameters)
        {}

        L2UeRbParameters &                  l2UeRbParameters_;
        L2FlowRbParameters &                l2FlowRbParameters_;
        L2PdcpRbParameters &                l2PdcpRbParameters_;
        L2RlcRbParameters &                 l2RlcRbParameters_;
        L2MacRbParameters &                 l2MacRbParameters_;

        L2RbConfigOutInfo                   l2RbConfigOutInfo_;
    };

    ///------------------------------------------------------------------------------------------
    /// This container is used to pass relevant UE Capability information to L2
    ///------------------------------------------------------------------------------------------
    class L2UeCapabilityContainer
    {
    public:
        L2UeCapabilityContainer()
          : ueCategory_(MIN_UE_CATEGORY),
            isFgiPresent_(false),
            featureGroupIndicators_(0xffffffff),
            ueSpecificRefSigsSupported_(false),
            ueTxAntennaSelectionSupported_(false),
            enhancedDualLayerTddSupportedR9_(false),
            isDeviceTypeR9Present_(false),
            deviceTypeR9_(LteApp::R1::NUM_OF_DEVICE_TYPE_R9)
        {}

        //***** IMPORTANT *****
        // when modifying data members be sure to update the debugDump function
        // as well.

        //////////////////////////////////////////////////////////////////////////////
        ///
        /// @brief Debug information is added to the specified string. The caller can
        ///        output the string to display the information.
        ///
        /// @param[out] outString - string containing the debug info.
        ///
        /// @returns - void
        ///
        //////////////////////////////////////////////////////////////////////////////
        void debugDump(std::string& outString) const;

        uint16_t ueCategory_;
        bool isFgiPresent_;
        uint32_t featureGroupIndicators_;
        bool ueSpecificRefSigsSupported_;
        bool ueTxAntennaSelectionSupported_;
        bool enhancedDualLayerTddSupportedR9_;
        bool isDeviceTypeR9Present_;
        LteApp::R1::DeviceTypeR9 deviceTypeR9_;
    };

    ///@todo L2 to fill in contents
    class MimoConfigData
    {
    public:
       MimoConfigData() {}

    };

    // Return code for the MacPhyReconfig request from L2
    typedef enum
    {
       MAC_PHY_RECONFIG_INVALID,  // Invalid status
       MAC_PHY_RECONFIG_OK,       // MacPhy Reconfig success
       MAC_PHY_RECONFIG_REJECTED  // MacPhy  Reconfig rejected
    } MacPhyReconfigStatus;

    typedef enum
    {
        TRIGGER_BY_L2_MAC_PHY_RECONF,
        TRIGGER_BY_L3_RB_SETUP,
        TRIGGER_BY_L3_REESTAB,
        TRIGGER_BY_L3_ANR_START,
        TRIGGER_BY_L3_ANR_STOP
    } RrcConnReconfigTriggerType;
    
    static const uint16_t maxNoOfConnectionId_c = 250;
    static const uint8_t maxBearerId_c = 0xF;

    // SON action mode definitions
    typedef enum
    {
    	SON_FREE_MODE = 0,       // free mode
    	SON_CONTROL_MODE = 1,    // control mode
    	SON_INVALID_MODE = 2     // always last index
    } SonActionModeType;

    typedef enum
    {
    	ANR_EVENT,          // event mode
    	ANR_PERIODICAL,     // periodical mode
    } AnrTriggerModeType;

    typedef enum
    {
    	CELL_AVAILIABLE,
    	CELL_PCI_INVALID,
    	CELL_INACTIVE,
    	CELL_STATE_INVALID
    }CellStateType;

    typedef enum
    {
    	CELL_PCI_VALID,
    	CELL_PCI_CONFLICT,
    	CELL_PCI_CONFUSION,
    	CELL_PCI_STATE_INVALID
    }CellPciStateType;

    typedef enum
    {
    	SON_ANR_NR_ADD_POLICY_AND,
    	SON_ANR_NR_ADD_POLICY_OR,
    	SON_ANR_NR_ADD_POLICY_INVALID
    }AnrNrAddPolicyType;

    typedef enum
    {
    	SON_ANR_NR_DEL_POLICY_AND,
    	SON_ANR_NR_DEL_POLICY_OR,
    	SON_ANR_NR_DEL_POLICY_INVALID
    }AnrNrDelPolicyType;

    typedef enum
    {
    	ANR_NR_ADD_WAIT_CONFIRM,
    	ANR_NR_VALID,
    	ANR_NR_DEL_WAIT_CONFIRM,
    	ANR_NR_INVALID,
    }AnrNrStatusType;

    typedef enum
    {
    	ENTRY_CHECKED,
    	ENTRY_NEW,
    	ENTRY_DEL,
    	ENTRY_MODIFY,
    	ENTRY_INVALID
    }NbrCellHdlStatusType;

    typedef enum
    {
    	CONFD_ADD_ENTRY,
    	CONFD_DEL_ENTRY,
        CONFD_UP_ENTRY_BY_KEY,
    	CONFD_UP_ENTRY,
        CONFD_END_APPLY,
        CONFD_END,
    	CONFD_OPER_IVALID
    }AppConfdMngtType;

    typedef enum
    {
      ANR_HO_X2,
      ANR_HO_S1,
      ANR_HO_X2_OK,
      ANR_HO_S1_OK,
      ANR_HO_X2_FAILURE,
      ANR_HO_S1_FAILURE,
      ANR_HO_RLF,
      ANR_HO_IVALID
    }AnrHoCntType;

    typedef enum
    {
      CALLP_CELL_AVAILABLE,
      CALLP_CELL_INVALID
    }CallpCellStateType;

    typedef enum
    {
        ANR_CGI_NBR_CELL_ADD,
        ANR_CGI_FOUND_TIME_INCR,
        ANR_CGI_PCI_CONFUSION,
        ANR_CGI_HDL_ERROR,
        ANR_CGI_HDL_INVALID,
    }AnrHdlCgiResultType;

    typedef enum
    {
        WAITING_CGI_FOR_HO,
        HANDLING_CGI_FOR_HO,
        CGI_FOR_HO_INVALID
    }UeCgiForHoStateType;

    typedef enum
    {
       ICIC_A3_IND_ENTER = 0,
       ICIC_A3_IND_EXIT = 1,
       ICIC_A3_IND_INVALID
    } IcicA3IndType;

    typedef enum
    {
       ICIC_STATE_DISABLED = 0,
       ICIC_STATE_ENABLED_STATIC = 1,
       ICIC_STATE_ENABLED_SEMI_STATIC = 2,
       ICIC_STATE_INVALID
    } IcicState;

    typedef enum
    {
       TRIGGER_BY_NON_ICIC = 0,
       TRIGGER_BY_ICIC_ENABLE = 1,
       TRIGGER_BY_ICIC_DISABLE = 2,
       TRIGGER_BY_ANR_ENABLE = 3,
       TRIGGER_BY_ANR_DISABLE = 4,
       TRIGGER_TYPE_INVALID
    } IcicAnrTriggerType;

    typedef enum
    {
        START_PRB_USAGE_REPORT,
        STOP_PRB_USAGE_REPORT,
        INVALID_PRB_USAGE_REQUEST_TYPE
    }PrbUsageReportRequestType;
} // LteApp

#endif
